package com.vis.mybatisflex.config;


import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 项目配置
 *
 * @author 王永吉
 * <p>
 * 1.拦截器配置
 * 2.资源配置
 * 3.跨域配置
 * 4.json配置
 * <p>
 * 98.初始化完成
 * 99.启动完成
 */
@Slf4j
@Configuration
public class WebConfig implements ApplicationContextAware, EnvironmentAware, WebMvcConfigurer, ApplicationListener<WebServerInitializedEvent> {

    /**
     * 2.资源配置
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("========================= 资源配置完成 =========================");
    }

    /**
     * 3.跨域配置
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路径
        registry.addMapping("/**")
                // 设置允许跨域请求的域名
                .allowedOriginPatterns("*")
                // 是否允许证书 不再默认开启
                .allowCredentials(true)
                // 设置允许的方法
                .allowedMethods("*")
                //跨域允许时间
                .maxAge(3600);
        log.info("========================= 跨域配置完成 =========================");
    }


    /**
     * 4.json
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            //            jacksonObjectMapperBuilder.serializerByType(Integer.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            //            jacksonObjectMapperBuilder.serializerByType(Integer.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(Float.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(Float.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(Double.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(Double.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(java.math.BigInteger.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.serializerByType(java.math.BigDecimal.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);

            builder.serializerByType(java.sql.Date.class, new DateSerializer(false, DateFormat.getDateInstance()));
            builder.serializerByType(java.sql.Timestamp.class, new DateSerializer(false, DateFormat.getDateTimeInstance()));
            builder.serializerByType(Date.class, new DateSerializer(false, DateFormat.getDateTimeInstance()));


            builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            builder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            builder.serializerByType(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

            builder.serializerByType(Date.class, new DateSerializer(false, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));
            builder.deserializerByType(Date.class, new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));

            builder.deserializerByType(java.sql.Date.class, new DateDeserializers.SqlDateDeserializer(new DateDeserializers.SqlDateDeserializer(), new SimpleDateFormat("yyyy-MM-dd"), "yyyy-MM-dd"));
            builder.deserializerByType(java.sql.Timestamp.class, new DateDeserializers.TimestampDeserializer(new DateDeserializers.TimestampDeserializer(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
            builder.deserializerByType(Date.class, new DateDeserializers.DateDeserializer(new DateDeserializers.DateDeserializer(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));

            builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer((DateTimeFormatter.ofPattern("HH:mm:ss"))));
        };

    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

    }

    @Override
    public void setEnvironment(Environment environment) {

    }

    //99.Spring启动完成
    @Override
    public void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) {
    }

    @Bean
    public RestTemplate restTemplate() {
        int timeout = 10000; // 连接和读取超时时间（毫秒）
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(timeout);
        factory.setReadTimeout(timeout);
        return new RestTemplate(factory);
    }

}
